package main
/*
Translate stream from one socket to another
*/

import (
	"net"
	"os"
	"fmt"
	//"io/ioutil"
	//"time"
)

var connIn *net.TCPConn
var connOut *net.TCPConn

func closeConnIn() {
	connIn.Close()
	connIn = nil
}

func closeConnOut() {
	connOut.Close()
	connOut = nil
}

func listenOut () {
	service := ":1500"
	tcpAddr, err := net.ResolveTCPAddr("ip4", service)
	checkError(err)

	listener, err := net.ListenTCP("tcp", tcpAddr)
	checkError(err)

	for {
		connOut, err = listener.AcceptTCP()
		if err != nil {
			continue
		}
    fmt.Println("proxy: open OUT");
		go handleClientOut()
	}
}

/*Listen connection from remote site*/
func listenIn () {
	service := ":1400"

	tcpAddr, err := net.ResolveTCPAddr("ip4", service)
	checkError(err)

	listener, err := net.ListenTCP("tcp", tcpAddr)
	checkError(err)

	for {
		connIn, err = listener.AcceptTCP()
		if err != nil {
			continue
		}
		fmt.Println("proxy: open IN");	
		go handleClientIn()
	}
}

/*Read from In and send to Out*/
func handleClientIn () {
	defer closeConnIn()
	defer fmt.Println("Proxy: close in")
	//defer connOut.Close()
	var buf [512]byte
	for {
		fmt.Println("Proxy: read IN")
		n, err := connIn.Read(buf[0:])
		if err != nil {
			return
		}
		fmt.Println(string(buf[0:]))
		if (connOut != nil ) {
			fmt.Println("Proxy: write OUT")
			_, err2 := connOut.Write(buf[0:n])
			if err2 != nil {
				closeConnOut()
				return
			}
		} else {
			fmt.Println("skip message from: " + connIn.LocalAddr().String());
			return
		}
	}
}

/*Read from Out and send to in*/
func handleClientOut () {
	defer closeConnOut()
	defer fmt.Println("Proxy: close out")
	//defer connIn.Close()
	var buf [512]byte
	for {
		n, err := connOut.Read(buf[0:])
		if err != nil {
			return
		}
		fmt.Println(string(buf[0:]))
		if (connIn != nil ) {
			_, err2 := connIn.Write(buf[0:n])
			if err2 != nil {
				closeConnIn()
				return
			}
		} else {
			fmt.Println("skip message from: " + connIn.LocalAddr().String());
		}
	}
}


func main() {

	go listenIn();
	listenOut();

	os.Exit(0)
}

func checkError(err error) {
	if err != nil {
		fmt.Fprintf(os.Stderr, "Fatal error: %s", err.Error())
		os.Exit(1)
	}
}
